#!/bin/bash
#
# rtpengine		Startup script for NGCP rtpengine
#
# chkconfig: 345 84 16
# description: NGCP rtpengine
#
# processname: rtpengine
# config: /etc/sysconfig/rtpengine
# pidfile: /run/rtpengine.pid
#
### BEGIN INIT INFO
# Provides: rtpengine
# Required-Start: $local_fs $network
# Short-Description: NGCP rtpengine
# Description: NGCP rtpengine 
### END INIT INFO

# Source function library.
. /etc/rc.d/init.d/functions

# defaults
TABLE=0

if [ -f /etc/sysconfig/rtpengine ]
then
        . /etc/sysconfig/rtpengine
else
	echo "Error: /etc/sysconfig/rtpengine not present" >&2
	exit 6
fi

rtpengine=/usr/sbin/rtpengine
prog=rtpengine
pidfile=${PIDFILE-/run/rtpengine.pid}
lockfile=${LOCKFILE-/var/lock/subsys/rtpengine}
configfile=${CONFIG_FILE-/etc/rtpengine/rtpengine.conf}
cachefile=/var/lib/ngcp-rtpengine/rtpengine.cfg
PIDFILE=${pidfile}
RETVAL=0
OPTS=""

build_opts() {
        # kernel table
	MODULE=0
	# variable from sysconfig is prefer then config
	if [[ -n "$TABLE" ]];then
		OPTS+=" --table=$TABLE"
		if [[ $TABLE -ge 0 ]];then
			MODULE=1
		fi
	else
		# configfile exists?
		if [ ! -f "$configfile" ];then
			echo "Error: $configfile not present" >&2
			exit 6
		fi

		# get table variable from config
		table="$(grep -Ei '^table' "$configfile" | cut -d\  -f3)"
		if [ -z "$table" ];then
			table="$(grep -Ei '^table' "$configfile" | cut -d= -f3)"
		fi

		# error if directive is not presented in config
		if [ -z "$table" ];then
			echo "Error: directive table= is not present in $configfile" >&2
			exit 6
		fi

		# enable iptables module if derective set and positive
		if [[ $table -ge 0 ]];then
			MODULE=1
		fi
	fi

	# interfaces
	if [[ -n "$RTP_IP" ]];then
		for IP in "${RTP_IP[@]}";do
			OPTS+=" --interface=$IP"
		done
	fi

	# options
	[[ "$FORK" == "no" ]] && OPTS+=" --foreground"
	[[ "$LOG_STDERR" == "yes" ]] && OPTS+=" --log-stderr"
	[[ "$FALLBACK" != "yes" ]] && OPTS+=" --no-fallback"
	[ -z "$CONFIG_FILE" ] || OPTS+=" --config-file=$CONFIG_FILE"
	[ -z "$CONFIG_SECTION" ] || OPTS+=" --config-section=$CONFIG_SECTION"
	[ -z "$ADDRESS" ] || OPTS+=" --interface=$ADDRESS"
	[ -z "$ADV_ADDRESS" ] || OPTS+="!$ADV_ADDRESS"
	[ -z "$ADDRESS_IPV6" ] || OPTS+=" --interface=$ADDRESS_IPV6"
	[ -z "$ADV_ADDRESS_IPV6" ] || OPTS+="!$ADV_ADDRESS_IPV6"
	[ -z "$LISTEN_TCP" ] || OPTS+=" --listen-tcp=$LISTEN_TCP"
	[ -z "$LISTEN_UDP" ] || OPTS+=" --listen-udp=$LISTEN_UDP"
	[ -z "$LISTEN_NG" ] || OPTS+=" --listen-ng=$LISTEN_NG"
	[ -z "$LISTEN_CLI" ] || OPTS+=" --listen-cli=$LISTEN_CLI"
	[ -z "$TIMEOUT" ] || OPTS+=" --timeout=$TIMEOUT"
	[ -z "$SILENT_TIMEOUT" ] || OPTS+=" --silent-timeout=$SILENT_TIMEOUT"
	[ -z "$FINAL_TIMEOUT" ] || OPTS+=" --final-timeout=$FINAL_TIMEOUT"
	[ -z "$PIDFILE" ] || OPTS+=" --pidfile=$PIDFILE"
	[ -z "$TOS" ] || OPTS+=" --tos=$TOS"
	[ -z "$PORT_MIN" ] || OPTS+=" --port-min=$PORT_MIN"
	[ -z "$PORT_MAX" ] || OPTS+=" --port-max=$PORT_MAX"
	[ -z "$REDIS" ] || [ -z "$REDIS_DB" ] || OPTS+=" --redis=$REDIS/$REDIS_DB"
	[ -z "$REDIS_AUTH_PW" ] || export RTPENGINE_REDIS_AUTH_PW="$REDIS_AUTH_PW"
	[ -z "$REDIS_WRITE" ] || [ -z "$REDIS_WRITE_DB" ] || OPTS+=" --redis-write=$REDIS_WRITE/$REDIS_WRITE_DB"
	[ -z "$REDIS_WRITE_AUTH_PW" ] || export RTPENGINE_REDIS_WRITE_AUTH_PW="$REDIS_WRITE_AUTH_PW"
	[ -z "$REDIS_NUM_THREADS" ] || OPTS+=" --redis-num-threads=$REDIS_NUM_THREADS"
	[ -z "$REDIS_EXPIRES" ] || OPTS+=" --redis-expires=$REDIS_EXPIRES"
	[ -z "$REDIS_MULTIKEY" ] || OPTS+=" --redis-multikey=$REDIS_MULTIKEY"
	[ -z "$NO_REDIS_REQUIRED" ] || { [ "$NO_REDIS_REQUIRED" != "1" ] && [ "$NO_REDIS_REQUIRED" != "yes" ] ; } || OPTS+=" --no-redis-required"
	[ -z "$B2B_URL" ] || OPTS+=" --b2b-url=$B2B_URL"
	[ -z "$LOG_LEVEL" ] || OPTS+=" --log-level=$LOG_LEVEL"
	[ -z "$LOG_FACILITY" ] || OPTS+=" --log-facility=$LOG_FACILITY"
	[ -z "$LOG_FACILITY_CDR" ] || OPTS+=" --log-facility-cdr=$LOG_FACILITY_CDR"
	[ -z "$LOG_FACILITY_RTCP" ] || OPTS+=" --log-facility-rtcp=$LOG_FACILITY_RTCP"
	[ -z "$NUM_THREADS" ] || OPTS+=" --num-threads=$NUM_THREADS"
	[ -z "$DELETE_DELAY" ] || OPTS+=" --delete-delay=$DELETE_DELAY"
	[ -z "$GRAPHITE" ] || OPTS+=" --graphite=$GRAPHITE"
	[ -z "$GRAPHITE_INTERVAL" ] || OPTS+=" --graphite-interval=$GRAPHITE_INTERVAL"
	[ -z "$GRAPHITE_PREFIX" ] || OPTS+=" --graphite-prefix=$GRAPHITE_PREFIX"
	[ -z "$MAX_SESSIONS" ] || OPTS+=" --max-sessions=$MAX_SESSIONS"
	[ -z "$HOMER" ] || OPTS+=" --homer=$HOMER"
	[ -z "$HOMER_PROTOCOL" ] || OPTS+=" --homer-protocol=$HOMER_PROTOCOL"
	[ -z "$HOMER_ID" ] || OPTS+=" --homer-id=$HOMER_ID"
	[ -z "$RECORDING_METHOD" ] || OPTS+=" --recording-method=$RECORDING_METHOD"
	[ -z "$RECORDING_FORMAT" ] || OPTS+=" --recording-format=$RECORDING_FORMAT"
	[ -z "$DTLS_PASSIVE" ] || { [ "$DTLS_PASSIVE" != "yes" ] && [ "$DTLS_PASSIVE" != "1" ] ; } || OPTS+=" --dtls-passive"

	# recording dir
	if [ -n "$RECORDING_DIR" ];then
		OPTS+=" --recording-dir=$RECORDING_DIR"
		if [ ! -d "$RECORDING_DIR" ]; then
			mkdir "$RECORDING_DIR" 2>/dev/null
			chmod 700 "$RECORDING_DIR" 2>/dev/null
		fi
	fi

}

start() {
	build_opts
	if [[ $MODULE == 1 ]];then
		echo "Loading module for in-kernel packet forwarding"
		rmmod xt_RTPENGINE 2> /dev/null
		if [[ -n "$SET_USER" ]];then
			if [[ -n "$SET_GROUP" ]];then
				proc_gid="$(grep "^$SET_GROUP:" /etc/group | cut -f3 -d:)"
			else
				proc_gid="$(id "$SET_USER" -g)"
			fi
			modprobe xt_RTPENGINE proc_uid="$(id "$SET_USER" -u)" proc_gid="$proc_gid"
		else
			modprobe xt_RTPENGINE
		fi
		if firewall-cmd --state 2>/dev/null ; then
			# Using firewalld
			# Need to check if the INPUT_prefilter chain is present (permanently)
			if ! firewall-cmd --permanent --direct --query-chain ipv4 filter INPUT_prefilter > /dev/null; then
				firewall-cmd --permanent --direct --add-chain ipv4 filter INPUT_prefilter
				firewall-cmd --permanent --direct --passthrough ipv4 -t filter -I INPUT -j INPUT_prefilter
				firewall-cmd --reload
			fi
				
			firewall-cmd --direct --add-chain ipv4 filter rtpengine
			firewall-cmd --direct --add-rule ipv4 filter INPUT_prefilter 0 -j rtpengine
			firewall-cmd --direct --add-rule ipv4 filter rtpengine 0 -p udp -j RTPENGINE --id "$TABLE"
			firewall-cmd --direct --add-rule ipv6 filter rtpengine 0 -p udp -j RTPENGINE --id "$TABLE"
  			firewall-cmd --reload
		else
			for fw in iptables ip6tables;do
				# We insert the rtpengine rule at the top of the input chain
				if ! $fw -t filter -C INPUT -j rtpengine 2> /dev/null; then
					$fw -N rtpengine
					$fw -t filter -I INPUT -j rtpengine
				fi
				if ! $fw -I rtpengine -p udp -j RTPENGINE --id "$TABLE" 2> /dev/null; then
					$fw -I rtpengine -p udp -j RTPENGINE --id "$TABLE"
				fi
			done
		fi

		cat <<EOF > "$cachefile"
CUR_TABLE=$TABLE
EOF
	fi
        echo -n $"Starting $prog: "
	if [[ -n "$SET_USER" ]];then
		# shellcheck disable=SC2086
		daemon --user "$SET_USER" --pidfile="${pidfile}" "$rtpengine" $OPTS
	else
		# shellcheck disable=SC2086
		daemon --pidfile="${pidfile}" "$rtpengine" $OPTS
	fi
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && touch "${lockfile}"
        return $RETVAL
}

stop() {
	echo -n $"Stopping $prog: "
	killproc -p "${pidfile}" "$rtpengine"
	RETVAL=$?
	echo
	if [ -f "$cachefile" ];then
		. "$cachefile"
		echo "Unloading module for in-kernel packet forwarding"
		echo "del $TABLE" > /proc/rtpengine/control
		if firewall-cmd --state 2>/dev/null; then
			firewall-cmd --direct --remove-rules ipv4 filter rtpengine
			firewall-cmd --direct --remove-rules ipv6 filter rtpengine
			firewall-cmd --direct --remove-rule ipv4 filter INPUT_prefilter 0 -j rtpengine
			firewall-cmd --direct --remove-chain ipv4 filter rtpengine
			firewall-cmd --reload
		else
			for fw in iptables ip6tables;do
				$fw -D rtpengine -p udp -j RTPENGINE --id "$CUR_TABLE"
				$fw -t filter -D INPUT -j rtpengine
				$fw -X rtpengine
			done
		fi
		rmmod xt_RTPENGINE
		rm -f "$cachefile"
	fi
 
	[ $RETVAL = 0 ] && rm -f "${lockfile}" "${pidfile}"
}

# See how we were called.
case "$1" in
  start)
	start
	;;
  stop)
	stop
	;;
  status)
        status -p "${pidfile}" "$rtpengine"
	RETVAL=$?
	;;
  restart)
	stop
	start
	;;
  condrestart|try-restart)
	if status -p "${pidfile}" "$rtpengine" >&/dev/null; then
		stop
		start
	fi
	;;
  *)
	echo $"Usage: $prog {start|stop|restart|condrestart|try-restart|status}"
	RETVAL=2
esac

exit $RETVAL
